package priv.blackbibo.application.activity;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.InputEvent;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.security.Key;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import priv.blackbibo.application.receiver.CountDownStatusBroadCastReceiver;
import priv.blackbibo.application.service.MediaPlaybackService;
import priv.blackbibo.application.R;
import priv.blackbibo.application.service.TimeCheckService;
import priv.blackbibo.application.contants.Constants;
import priv.blackbibo.application.contants.StatusEnum;

import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;

public class MainActivity extends BaseActivity  implements View.OnClickListener, View.OnFocusChangeListener {

    public static final int PLAT_MUSIC = 1;
    public static final int PAUSE_MUSIC = 2;
    public static final int STOP_MUSIC = 3;

    private static final String TAG = "drinking";

    private TextView timeview = null;
    private TextView countDownView = null;
    private Button startBtn = null;
    private EditText rateText = null;
    private TextView endTimeDateView = null;
    private TextView endTimeTimeView = null;
    private TextView nextTimeLabel = null;
    private TextView labelOfInput = null;
    private TextView labelOfDiemession = null;

    private StepThread stepThread = null;

    private Handler handler = new Handler();
    private String channelId = "blackbibo";

    private AlertDialog alertDialog;

    private static MainActivity mainActivity;

    private int notificationId = 10101;

    Configuration getConfiguration(){
        return new Configuration(this);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mainActivity = this;
        checkStatus();
        initViewAndBindListener();
        refreshMainView();
        startStepThread();
        registBroadcast();
    }

    public void checkStatus(){
        Configuration configuration = getConfiguration();
        if (configuration.getStatus() == StatusEnum.NOTICED.status){
            this.callNoticeScroll();
        }else if (configuration.getStatus() == StatusEnum.STARTED.status || configuration.getStatus() == StatusEnum.STARTING.status){
            //通知后台服务开始倒计时
            this.tellBackwardToStartCountdown();
        }
    }

    public void startStepThread(){
        this.stepThread = new StepThread();
        this.stepThread.start();
    }

    public void registBroadcast(){
        IntentFilter intentFilter = new IntentFilter(Constants.COUNT_DOWN_STATUS);
        LocalBroadcastManager.getInstance(this).registerReceiver(new CountDownStatusBroadCastReceiver(), intentFilter);
    }

    public void initViewAndBindListener(){
        timeview = this.findViewById(R.id.timeview);
        countDownView = this.findViewById(R.id.countdownview);
        rateText = this.findViewById(R.id.rateText);
        endTimeDateView = this.findViewById(R.id.endTimeViewDate);
        endTimeTimeView = this.findViewById(R.id.endTimeViewTime);
        nextTimeLabel = this.findViewById(R.id.nextTimeLable);
        labelOfInput = this.findViewById(R.id.labelOfInput);
        labelOfDiemession = this.findViewById(R.id.labelOfDiemession);

        startBtn = this.findViewById(R.id.startBtn);

        timeview.setOnClickListener(this);
        startBtn.setOnClickListener(this);
        startBtn.setBackgroundResource(R.drawable.round_green_btn_shape);
        rateText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                String newValue = s.toString();
                if (newValue.equals("")){
                    refreshMainView(false);
                }else if (!newValue.matches("\\d*")){
                    s.clear();
                }else {
                    int value = Integer.valueOf(s.toString());
                    if (value*Constants.secondsPerRound > 24*3600){
                        Toast.makeText(mainActivity, "时间太长了", Toast.LENGTH_SHORT).show();
                        s.clear();
                        return;
                    }
                    getConfiguration().setInputValue(value);
                    refreshMainView(false);
                }
            }
        });
        rateText.setOnFocusChangeListener(this::onFocusChange);
    }

    public void notification(){
        Log.d(TAG, "notification: start");
        // Create an explicit intent for an Activity in your app

        Intent intent = new Intent(this, MainActivity.class);
        intent.setFlags(FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
        Calendar calendar = getConfiguration().getHeadTime();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm");
        String message = simpleDateFormat.format(calendar.getTime()) + " 生活的每一刻，不能没有水的滋润";
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this, channelId)
                .setSmallIcon(R.mipmap.ic_launcher)
                .setContentTitle("时间到了")
                .setContentText(message)
                .setStyle(new NotificationCompat.BigTextStyle()
                        .bigText(message))
                .setContentIntent(pendingIntent)
                .setPriority(NotificationCompat.PRIORITY_MAX);
        Notification notification = builder.build();
        NotificationManager notificationManager = getNotificationManager();
        notificationManager.cancel(notificationId);
        notificationManager.notify(notificationId,notification);
        Log.d(TAG, "notification: finish");
    }

    public void clearNotifications(){
        getNotificationManager().cancel(notificationId);
    }

    private NotificationManager getNotificationManager() {
        NotificationManager notificationManager = null;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            notificationManager = getSystemService(NotificationManager.class);
            NotificationChannel notificationChannel = null;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                notificationChannel = new NotificationChannel(channelId,"blackbibo", NotificationManager.IMPORTANCE_HIGH);
            }
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                notificationManager.createNotificationChannel(notificationChannel);
            }
        }
        return notificationManager;
    }

    public static void callStart(){
        mainActivity.clearNotice();
        mainActivity.start();
    }

    /**
     * 用户点击开始按钮
     */
    public void start(){
        //更改状态
        this.getConfiguration().setStatus(StatusEnum.STARTING.status);
        //保存当前数据
        this.generateNewValue();
        //更新组件
        this.refreshMainView();
        //通知后台服务开始倒计时
        this.tellBackwardToStartCountdown();
    }

    public void generateNewValue(){
        //已经在监听器里设置了
        Configuration configuration = getConfiguration();
        configuration.setInputValue(configuration.getInputValue());
    }

    public void interrupt(){
        //更改状态
        this.getConfiguration().setStatus(StatusEnum.INIT.status);
        //更新组件
        this.refreshMainView();
        //通知后台服务开始倒计时
        this.tellBackwardToStopCountdown();
        //停止播放音乐和震动
        this.clearNotice();
        this.clearNotifications();
    }

    public void letUserKnown() {
        getConfiguration().setStatus(StatusEnum.END_WAITING_NOTICE.status);
        //通知栏通知
        notification();
        //播放音乐，同时震动
        playMusic();
        //弹窗
//        alert(getString(R.string.notice_message));
        callNoticeScroll();
        getConfiguration().setStatus(StatusEnum.NOTICED.status);
    }

    private void playMusic() {
        Log.d(TAG, "play: ");
        //启动服务，播放音乐
        Intent intent=new Intent(this, MediaPlaybackService.class);
        intent.putExtra("type",PLAT_MUSIC);
        startService(intent);
    }

    private void alert(String messsage) {
        if (alertDialog == null){
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage(messsage);
            builder.setPositiveButton("好的", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                @Override
                public void onDismiss(DialogInterface dialog) {
                    Log.d(TAG, "onDismiss: lost");
                    dialog.cancel();
                }
            });
            builder.setOnCancelListener(new DialogInterface.OnCancelListener() {
                @Override
                public void onCancel(DialogInterface dialog) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            clearNotice();
                            start();
                        }
                    });
                }
            });
            alertDialog = builder.create();
        }

        if (!this.isFinishing() && !alertDialog.isShowing()){
            alertDialog.show();
        }
    }

    public void clearNotice(){
        this.stopMusic();
        this.clearNotifications();
    }

    private void stopMusic() {
        //启动服务，播放音乐
        Intent intent=new Intent(this,MediaPlaybackService.class);
        intent.putExtra("type",STOP_MUSIC);
        startService(intent);
    }

    private void tellBackwardToStartCountdown() {
        Intent intent = new Intent(this, TimeCheckService.class);
        intent.putExtra("countdown",getConfiguration().getInputValue());
        intent.putExtra("action","start");
        startService(intent);
    }

    private void tellBackwardToStopCountdown() {
        Intent intent = new Intent(this, TimeCheckService.class);
        intent.putExtra("action", "stop");
        startService(intent);
    }

    /**
     * 获取当前时间
     * @return
     */
    private String currentTime(){
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(getString(R.string.time_hour_and_seconds_patterns));
        return simpleDateFormat.format(new Date());
    }


    @Override
    public void onFocusChange(View v, boolean hasFocus) {

    }

    @Override
    public void onPointerCaptureChanged(boolean hasCapture) {

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.timeview:
                break;
            case R.id.startBtn:
                rateText.clearFocus();
                Configuration configuration = getConfiguration();
                StatusEnum statusEnum = StatusEnum.get(configuration.getStatus());
                switch (statusEnum){
                    case INIT:
                    case INPUTTING:
                        start();
                        break;
                    case STARTING:
                    case STARTED:
                    case END_WAITING_NOTICE:
                    case NOTICED:
                        interrupt();
                        break;
                    case END:
                    default:
                }
                break;
        }
    }

    public void refreshMainView(){
        refreshMainView(true);
    }
    public void refreshMainView(boolean rateTextUpdate){
        Configuration configuration = getConfiguration();
        StatusEnum statusEnum = StatusEnum.get(configuration.getStatus());
        switch (statusEnum){
            case INIT:
                rateText.setEnabled(true);
                startBtn.setText(getString(R.string.start_name));
                startBtn.setBackgroundResource(R.drawable.round_green_btn_shape);
                if (rateTextUpdate){
                    rateText.setText(String.valueOf(configuration.getInputValue()));
                }
                Date headTime = configuration.getHeadTime().getTime();
                endTimeDateView.setText(new SimpleDateFormat(getString(R.string.time_date_patterns)).format(headTime));
                endTimeTimeView.setText(new SimpleDateFormat(getString(R.string.time_time_patterns)).format(headTime));
                countDownView.setText(String.valueOf(configuration.getInputValue()*Constants.secondsPerRound));
                labelOfInput.setTextColor(getResources().getColor(R.color.text_common_white));
                rateText.setTextColor(getResources().getColor(R.color.text_common_white));
                labelOfDiemession.setTextColor(getResources().getColor(R.color.text_common_white));
                nextTimeLabel.setTextColor(getResources().getColor(R.color.text_common_drark));
                endTimeDateView.setTextColor(getResources().getColor(R.color.text_common_drark));
                endTimeTimeView.setTextColor(getResources().getColor(R.color.text_common_drark));
                rateText.requestFocus();
                break;
            case INPUTTING:
                Date inputTime = configuration.getHeadTime().getTime();
                endTimeDateView.setText(new SimpleDateFormat(getString(R.string.time_date_patterns)).format(inputTime));
                endTimeTimeView.setText(new SimpleDateFormat(getString(R.string.time_time_patterns)).format(inputTime));
                countDownView.setText(String.valueOf(configuration.getInputValue()*Constants.secondsPerRound));
                break;
            case STARTING:
                rateText.setEnabled(false);
            case STARTED:
                startBtn.setText(getString(R.string.stop_name));
                startBtn.setBackgroundResource(R.drawable.round_red_btn_shape);
                long sub;
                Calendar now = Calendar.getInstance();
                long nowTimestamp = now.getTimeInMillis();
                long stopTimestamp = configuration.getHeadTime().getTimeInMillis();
                sub = (stopTimestamp - nowTimestamp) / 1000;
                if (sub < 0){
                    sub = 0;
                }
                countDownView.setText(String.valueOf(sub));
                Date roundTime = configuration.getHeadTime().getTime();
                endTimeDateView.setText(new SimpleDateFormat(getString(R.string.time_date_patterns)).format(roundTime));
                endTimeTimeView.setText(new SimpleDateFormat(getString(R.string.time_time_patterns)).format(roundTime));

                labelOfInput.setTextColor(getResources().getColor(R.color.text_common_drark));
                rateText.setTextColor(getResources().getColor(R.color.text_common_drark));
                labelOfDiemession.setTextColor(getResources().getColor(R.color.text_common_drark));
                nextTimeLabel.setTextColor(getResources().getColor(R.color.text_common_white));
                endTimeDateView.setTextColor(getResources().getColor(R.color.text_common_white));
                endTimeTimeView.setTextColor(getResources().getColor(R.color.text_common_white));
                break;
            case END_WAITING_NOTICE:
            case NOTICED:
            case END:
                rateText.setEnabled(true);
                startBtn.setText(getString(R.string.start_name));
                startBtn.setBackgroundResource(R.drawable.round_green_btn_shape);
                countDownView.setText(getString(R.string.defualt_countdown));
                break;
                default:
        }
        //更新输入狂
        //跟新button
        //更新倒计时
        //更新截止时间
    }

    class StepThread extends Thread{
        @Override
        public void run() {
            for (;;){
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        String cuurentTimeStr =  currentTime();
                        if (!cuurentTimeStr.equals(timeview.getText().toString())){
                            timeview.setText(cuurentTimeStr);
                        }
                    }
                });
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    break;
                }
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d(TAG, "onResume: ");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d(TAG, "onDestroy: ");
    }

    public static void refreshUi(){
        if (mainActivity == null) return;
        mainActivity.refreshMainView();
    }

    public static void noticeUserToDrink(){
        if (mainActivity == null) return;
        mainActivity.letUserKnown();
    }

    public void callNoticeScroll(){
        Intent intent = new Intent(this,NoticeActivity.class);
        intent.addFlags(FLAG_ACTIVITY_NEW_TASK);
        mainActivity.startActivity(intent);
    }

    class Configuration {
        private Calendar headTime;
        private int inputValue;
        //0,初始化,
        // 1,用户正在输入数据,
        // 2，开始倒计时时,
        // 3,正在倒计时,
        // 4,结束倒计时，未通知用户，
        // 5,已通知用户，
        // 6，倒计时已终止，等待用户开启
        private int status;
        private SharedPreferences sharedPreferences;

        public Configuration(Context context) {
            sharedPreferences = context.getSharedPreferences(getString(R.string.key_configuration),Context.MODE_PRIVATE);
            inputValue = sharedPreferences.getInt(getString(R.string.config_key_inputValue), Integer.valueOf(getString(R.string.defualt_countdown)));
            String headTimeString = sharedPreferences.getString(getString(R.string.config_key_headTime), getString(R.string.stop_time_default));
            status = sharedPreferences.getInt(getString(R.string.config_key_status),StatusEnum.INIT.status);

            if (headTimeString.equals(getString(R.string.stop_time_default))) {
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.SECOND, inputValue * Constants.secondsPerRound);
                headTime = calendar;
            }else {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(getString(R.string.time_patterns));
                try {
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(simpleDateFormat.parse(headTimeString));
                    headTime = calendar;
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }

        public Calendar getHeadTime() {
            return headTime;
        }

        public void setHeadTime(Calendar headTime) {
            this.headTime = headTime;
        }

        public int getInputValue() {
            return inputValue;
        }

        public void setInputValue(int inputValue) {
            this.inputValue = inputValue;
            sharedPreferences.edit().putInt(getString(R.string.config_key_inputValue), inputValue).apply();
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.SECOND,inputValue*Constants.secondsPerRound);
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat(getString(R.string.time_patterns));
            String newHeadTime = simpleDateFormat.format(calendar.getTime());
            Log.d(TAG, "setInputValue: new head time "+newHeadTime);
            this.headTime = calendar;
            sharedPreferences.edit().putString(getString(R.string.config_key_headTime),newHeadTime).apply();
        }

        public int getStatus() {
            return status;
        }

        public void setStatus(int status) {
            this.status = status;
            sharedPreferences.edit().putInt(getString(R.string.config_key_status), status).apply();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
    }

    @Override
    public void onConfigurationChanged(android.content.res.Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (newConfig.orientation == android.content.res.Configuration.ORIENTATION_LANDSCAPE) {
            setContentView(R.layout.activity_main_landover);

//            WindowManager.LayoutParams lp = getWindow().getAttributes();
//            lp.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN;
//            getWindow().setAttributes(lp);
//            getWindow().addFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

        }else {

//            WindowManager.LayoutParams attr = getWindow().getAttributes();
//            attr.flags &= (~WindowManager.LayoutParams.FLAG_FULLSCREEN);
//            getWindow().setAttributes(attr);
//            getWindow().clearFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);

            setContentView(R.layout.activity_main);
        }
        initViewAndBindListener();
        refreshMainView();
    }

//    @Override
//    public boolean onKeyDown(int keyCode, KeyEvent event) {
//        if (keyCode == KeyEvent.KEYCODE_BACK){
//            Log.d(TAG, "onKeyDown: back");
//            return false;
//        }else {
//            return super.onKeyDown(keyCode, event);
//        }
//    }
}
